﻿using GKQC.Common;
using GKQC.DbHelper.DbModels;
using GKQC.DbHelper.ViewModels;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Speech.Recognition;
using System.Speech.Synthesis;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Xml;

namespace GKQC.Machine
{
    public partial class FormCaliper_Ort : QcFormBase, IMachine
    {
        bool isOn = false;
        bool isGettingData = false;
        List<ElectricViewModel> _ElectricViewModels;
        int currentRowIndex = 0;
        bool isChangRowByCode = false;
        StandardView _StandardView;
        Form parentForm;

        private SpeechRecognitionEngine _recognizer = new SpeechRecognitionEngine();
        private SpeechSynthesizer synth = new SpeechSynthesizer();

        public bool IsClosing { get; set; }
        public FormCaliper_Ort(Form parentForm, UserModel user, List<ElectricViewModel> sizeViewModels, StandardView stardardView)
        {
            InitializeComponent();

            this.dataGridView1.Dock = DockStyle.Fill;
            this.dataGridView1.AutoGenerateColumns = false;
            this.dataGridView1.CellFormatting +=
                new System.Windows.Forms.DataGridViewCellFormattingEventHandler(DataGridViewSet.CellFormatting);
            this.dataGridView1.CellFormatting +=
                new System.Windows.Forms.DataGridViewCellFormattingEventHandler(DataGridViewSet.CellFormattingForColor);
            //new System.Windows.Forms.DataGridViewCellFormattingEventHandler(DataGridViewSet.CellFormattingStrikeout);
            this._ElectricViewModels = sizeViewModels;
            this._StandardView = stardardView;
            this.parentForm = parentForm;
            this.dataGridView1.DataSource = new BindingList<ElectricViewModel>(this._ElectricViewModels);

            if(parentForm.Name == "FormOrt")
            {
                foreach(DataGridViewColumn c in dataGridView1.Columns)
                {
                    if(c != ColH && c!= ColL1 && c != ColD && c != ColL && c != ColC)
                    {
                        c.Visible = false;
                    }
                    
                    if(c == ColH)
                    {
                        c.HeaderText = "High";
                    }
                    else if (c == ColL1)
                    {
                        c.HeaderText = "Visual";
                    }
                }
            }

            SetStardardInGridHeadText();

            GetPortBuad();
            Start(null, null);

        }

        void SetStardardInGridHeadText()
        {
            try
            {
                if (_StandardView != null)
                {
                    if (this._StandardView.DMax > 0)
                        ColD.HeaderText =
                        ColD.HeaderText + Environment.NewLine +
                        _StandardView.DMin + "~" + _StandardView.DMax;

                    if (this._StandardView.LMax > 0)
                        ColL.HeaderText =
                        ColL.HeaderText + Environment.NewLine +
                        _StandardView.LMin + "~" + _StandardView.LMax;
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
            }
        }

        private void label4_Click(object sender, EventArgs e)
        {

        }

        private void Start(object sender, EventArgs e)
        {
            try
            {
                if (!isOn)
                {
                    timer1.Enabled = true;
                    sp.Open();
                }
                else
                {
                    timer1.Enabled = false;
                    Thread.Sleep(300);
                    sp.Close();
                }

                isOn = !isOn;
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
            }
        }

        int ZeroCount = 0;
        private void timer1_Tick(object sender, EventArgs e)
        {
            try
            {
                if (isGettingData) return;
                isGettingData = true;
                if (isOn)
                {
                    string msg = string.Empty;
                    byte[] readBuffer = new byte[this.sp.BytesToRead];
                    this.sp.Read(readBuffer, 0, readBuffer.Length);
                    //msg = System.Text.Encoding.ASCII.GetString(readBuffer);
                    msg = System.Text.Encoding.Default.GetString(readBuffer);
                    if (msg.Contains("S"))
                    {
                        btnGet.PerformClick();
                        this.sp.DiscardInBuffer();
                        return;
                    }

                    if (msg.Length < 10) return;
                    msg = msg.Substring(msg.Length - 10, 9);
                    decimal value = 0m;
                    decimal.TryParse(msg, out value);

                    if (value == 0)
                        ZeroCount++;

                    if (ZeroCount < 3 && value == 0) return;

                    ZeroCount = 0;
                    lblValue.Text = value.ToString();
                }
                else
                {
                    lblValue.Text = "0.00";
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
            }
            finally
            {
                isGettingData = false;
#if DEBUG
                lblValue.Text = (RandomSugar.GetFormatedNumeric(3200, 3500) / 100m).ToString();
#endif
            }
        }

        private void btnGet_Click(object sender, EventArgs e)
        {
            if (dataGridView1.CurrentCell == null)
            {
                MessageBox.Show("請先選擇要檢測的欄位！", "提示");
                return;
            }

            if (currentRowIndex > dataGridView1.Rows.Count - 1) return;

            double value = 0;
            if (!double.TryParse(lblValue.Text, out value)) return;
            if (value == 0) return;

            try
            {
                dataGridView1.CurrentCell.Value = value;
                ElectricViewModel view = dataGridView1.CurrentRow.DataBoundItem as ElectricViewModel;
                if(view != null) IsValid(view, value);
                dataGridView1.Refresh();
                currentRowIndex++;
                if (currentRowIndex <= this.dataGridView1.Rows.Count - 1)
                {
                    isChangRowByCode = true;
                    this.dataGridView1.Rows[currentRowIndex].Cells[this.dataGridView1.CurrentCell.ColumnIndex].Selected = true;
                    isChangRowByCode = false;
                }
                else if(this.dataGridView1.CurrentCell.ColumnIndex < this.dataGridView1.Columns.Count - 1)
                {
                    //一列录入完毕自动跳到下一列
                    currentRowIndex = 0;
                    isChangRowByCode = true;
                    int cIndex = this.dataGridView1.CurrentCell.ColumnIndex+1;
                    for (int i = cIndex; i < this.dataGridView1.Columns.Count; i++)
                    {
                        if(this.dataGridView1.Rows[currentRowIndex].Cells[i].Visible)
                        {
                            this.dataGridView1.Rows[currentRowIndex].Cells[i].Selected = true;
                            break;
                        }
                        //this.dataGridView1.Rows[currentRowIndex].Cells[this.dataGridView1.CurrentCell.ColumnIndex + 1].Selected = true;
                    }
                    isChangRowByCode = false;
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
            }
        }

        bool IsValid(ElectricViewModel view, double value)
        {
            bool flag = true;
            ItemCode itemCode = ItemCode.D;
            if (dataGridView1.Columns[dataGridView1.CurrentCell.ColumnIndex] == ColD)
                itemCode = ItemCode.D;
            DataGridViewColumn column = dataGridView1.Columns[dataGridView1.CurrentCell.ColumnIndex];
            if (column == null) return flag;

            string fieldName = column.DataPropertyName;
            if (string.IsNullOrWhiteSpace(fieldName)) return flag;
            Enum.TryParse(fieldName, out itemCode);

            flag = _StandardView.IsValid(itemCode, value);
            switch (itemCode)
            {
                case ItemCode.D:
                    view.DisValid = flag;
                    break;
                case ItemCode.L:
                    view.LisValid = flag;
                    break;
                case ItemCode.H:
                    view.HisValid = flag;
                    break;
                case ItemCode.C:
                    view.CisValid = flag;
                    break;
                case ItemCode.L1:
                    view.L1isValid = flag;
                    break;
                default:
                    try
                    {
                        var proisValid = typeof(ElectricViewModel).GetProperty(itemCode + StandardView.isValidString);
                        if (proisValid != null)
                        {
                            proisValid.SetValue(view, flag, null);
                        }
                    }
                    catch (Exception ex)
                    {
                        Logger.LogError(ex);
                        MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace);
                    }
                    break;
            }

            return flag;
        }
    

        private void dataGridView1_SelectionChanged(object sender, EventArgs e)
        {
            if (isChangRowByCode) return;
            if (dataGridView1.CurrentCell != null && dataGridView1.CurrentCell.RowIndex < dataGridView1.Rows.Count - 1)
                currentRowIndex = dataGridView1.CurrentCell.RowIndex;
        }

        private void Grid_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
        {
            Common.DataGridViewSet.RowPostPaint(sender, e);
        }

        //獲取端口和波特率
        private void GetPortBuad()
        {
            Settings.GetPortBuad(sp, Settings.MachineType.Caliper);
        }

        #region 右鍵菜單
        private void tsmClear_Click(object sender, EventArgs e)
        {
            if (dataGridView1.CurrentCell != null) dataGridView1.CurrentCell.Value = null;
        }

        private void tsmClearColumn_Click(object sender, EventArgs e)
        {
            try
            {
                if (dataGridView1.CurrentCell != null)
                {
                    int colmnIndex = dataGridView1.CurrentCell.ColumnIndex;
                    for (int i = 0; i < dataGridView1.Rows.Count; i++)
                    {
                        dataGridView1.Rows[i].Cells[colmnIndex].Value = null;
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
                MessageBox.Show(ex.Message, "異常S0036", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            //if (dataGridView1.CurrentRow != null)
            //{
            //    var v = dataGridView1.CurrentRow.DataBoundItem as SizeViewModel;
            //    if (v != null)
            //    {
            //        v.Clear();
            //        this.dataGridView1.Refresh();
            //    }
            //}
        }

        private void tsmClearAll_Click(object sender, EventArgs e)
        {
            if (_ElectricViewModels != null && _ElectricViewModels.Count > 0)
            {
                foreach (ElectricViewModel v in _ElectricViewModels)
                {
                    v.Clear();
                }
                this.dataGridView1.Refresh();
            }
        }
        #endregion 右鍵菜單

        bool isESCcancel = false;
        private void dataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            try
            {
                if (dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].ValueType == typeof(Double)
                    || dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].ValueType == typeof(Decimal))
                {
                    dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = 0;
                    e.Cancel = true;
                    SendKeys.Send("{ESC}");
                    isESCcancel = true;
                }
            }
            catch (Exception ex)
            {

            }
        }

        private void FormCaliper_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                IsClosing = true;
                var m = parentForm.GetType().GetMethod("RefreshTestGrid");
                if (m != null && m.GetParameters().Length == 1)
                    m.Invoke(parentForm, new object[] { 1 });
                else if((m != null && m.GetParameters().Length == 2))
                    m.Invoke(parentForm, new object[] { null,false });
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
                MessageBox.Show(ex.Message, "異常S0025");
            }
        }

        private void FormCaliper_Load(object sender, EventArgs e)
        {
            //SpeechRecognition sr = new SpeechRecognition(new string[] { "您好", "电视" });
            //sr.BeginRec(label1); 
        }

        public void RefreshGrid()
        {
            dataGridView1.Refresh();
        }

        private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                if (isESCcancel)
                {
                    isESCcancel = false;
                    if (e.RowIndex < dataGridView1.Rows.Count - 1)
                    {

                        dataGridView1.CurrentCell = dataGridView1.Rows[e.RowIndex + 1].Cells[e.ColumnIndex];
                    }
                }
            }
            catch (Exception ex)
            {

            }
        }

        bool isChangingColumn = false;
        private void dataGridView1_CellValidated(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                var view = this.dataGridView1.CurrentRow.DataBoundItem as ElectricViewModel;
                if (view == null) return;

                double value = 0;
                if (dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value == null) return;
                double.TryParse(dataGridView1.Rows[e.RowIndex]
                    .Cells[e.ColumnIndex].Value.ToString(), out value);

                var c = this.dataGridView1.Columns[e.ColumnIndex];

                if (c.DataPropertyName.StartsWith("UM") && value < 1)
                    value = value * 1000;

                var proisValid = typeof(ElectricViewModel).GetProperty(
                    c.DataPropertyName + StandardView.isValidString);
                if (proisValid != null)
                {
                    bool isvalid = true;
                    
                        isvalid =
                    _StandardView.IsValid(c.DataPropertyName, value,0);
                    proisValid.SetValue(view, isvalid, null);

                    if (value > 0 && !isvalid)
                        splitContainer2.Panel2.BackColor = Color.Red;
                    else
                        splitContainer2.Panel2.BackColor = Color.Transparent;
                }


                int currtentColumnIndex = e.ColumnIndex;
                int currentRowIndex = e.RowIndex;


                if ((currentRowIndex == dataGridView1.Rows.Count - 1) && (currtentColumnIndex < dataGridView1.Columns.Count - 1)
                    && !isChangingColumn)
                {
                    isChangingColumn = true;
                    for (int i = currtentColumnIndex + 1; i < dataGridView1.Columns.Count; i++)
                    {
                        if (dataGridView1.Columns[i].Visible)
                        {
                            dataGridView1.ClearSelection();
                            dataGridView1.CurrentCell = dataGridView1.Rows[0].Cells[i];
                            break;
                        }
                    }
                }

                this.dataGridView1.Refresh();
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
            }
            finally
            {
                isChangingColumn = false;
            }
        }
    }
}
